package com.restaurant.springboot.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.restaurant.springboot.entity.UserEntity;
import com.restaurant.springboot.exception.TokenInvalidException;
import com.restaurant.springboot.service.UserService;
import com.restaurant.springboot.utils.Constant;
import com.restaurant.springboot.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * @Author jack
 * @Date:2019/7/30 20:33
 */
@Aspect
@Component
public class TokenAspects {

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    UserService userService;

    @Pointcut("@annotation(com.restaurant.springboot.annotation.TokenAuth)")
    public void authUser(){}

    @ResponseBody
    @Before("authUser()")
    public void auth(JoinPoint joinPoint) throws TokenInvalidException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();;
        if(!validToken(request)){
            throw new TokenInvalidException("Token无效");
        }
    }


    private boolean validToken(HttpServletRequest request){
        String header = request.getHeader("User-Agent");
        String xToken = request.getHeader("X-Token");
        if(xToken == null || header == null){
            return false;
        }
        try {
            Claims claims = jwtUtil.parseJWT(xToken);
            //check id
            if(!Constant.JWT_ID.equals(claims.getId())){
                return  false;
            }
            long nowMillis = System.currentTimeMillis();
            Date now = new Date(nowMillis);
            //check time
            if(now.compareTo(claims.getExpiration()) > 0 ){
                return  false;   //out-of time
            }
            JSONObject object = JSON.parseObject(claims.getSubject());
            Integer tokenUserId =  object.getInteger("userId");
            String tokenUserAgent = (String) object.get("userAgent");
            if(tokenUserAgent == null || tokenUserId == null){
                return false;
            }
            if (!header.equals(tokenUserAgent)) {
                return false;
            }
            HttpSession session = request.getSession();
            UserEntity userEntity = userService.getUserById(tokenUserId);
            if(userEntity == null){
                return false;
            }
            session.setAttribute("user", userEntity);
        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        }
        return true;
    }
}